
namespace SharpTalk.Client.WpfApplication
{
    using Core.Base;
    using System;
    using System.Collections;

    /// <summary>
    /// 
    /// </summary>
    public sealed class ApplicationServiceStates 
        : PropertyChangedBase
    {
        private static readonly int STATES_COUNT = Enum.GetValues(typeof(ApplicationServiceStatesEnum)).Length;
        private readonly BitArray _states;

        /// <summary>
        /// Creates a new instance
        /// </summary>
        public ApplicationServiceStates()
        {
           _states = new BitArray(STATES_COUNT, false);
        }
        /// <summary>
        /// Obtains the States values
        /// </summary>
        public bool[] Values
        {
            get
            {
                var values = new bool[_states.Length];
                _states.CopyTo(values,0);
                return values;
            }
        }
        /// <summary>
        /// Determines if the Application is Busy
        /// </summary>
        public bool IsBusy
        {
            get
            {
                return  Initializing || 
                        SendingMessage || 
                        ReceivingMessage || 
                        CreatingUser || 
                        DeletingUser || 
                        UpdatingUser || 
                        CreatingRoom || 
                        JoiningRoom || 
                        LeavingRoom || 
                        FindingRoom ||
                        UpdatingRoom;
            }
        }
        /// <summary>
        /// Obtains or defines a state
        /// </summary>
        /// <param name="index">The state index</param>
        /// <returns>True or false</returns>
        private bool this[int index]
        {
            get
            {
                if(index > STATES_COUNT)throw new IndexOutOfRangeException();
                return _states[index];
            }
            set
            {
                if (index > STATES_COUNT) throw new IndexOutOfRangeException();
                _states.Set(index, value);
                NotifyPropertyChange(()=>Values);
            }
        }
        /// <summary>
        /// Obtains or defines a state
        /// </summary>
        /// <param name="state">the enum State value</param>
        /// <returns>True or false</returns>
        public bool this[ApplicationServiceStatesEnum state]
        {
            get
            {
                return this[(int)state];
            }
            set
            {
                this[(int)state] = value;
            }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "Closing" State.
        /// </summary>
        /// <remarks>
        /// That state doesn't set IsBusy to true.
        /// </remarks>
        public bool Closing
        {
            get { return  this[ApplicationServiceStatesEnum.Closing]; }
            set { this[ApplicationServiceStatesEnum.Closing] = value; NotifyPropertyChange(() => Closing); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "Initializing" State
        /// </summary>
        public bool Initializing
        {
            get { return this[ApplicationServiceStatesEnum.Initializing]; }
            set
            {
                this[ApplicationServiceStatesEnum.Initializing] = value; 
                NotifyPropertyChange(() => Initializing, () => IsBusy);
                
            }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "SendingMessage" State
        /// </summary>
        public bool SendingMessage
        {
            get { return this[ApplicationServiceStatesEnum.SendingMessage]; }
            set { this[ApplicationServiceStatesEnum.SendingMessage] = value; NotifyPropertyChange(() => SendingMessage, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "ReceivingMessage" State
        /// </summary>
        public bool ReceivingMessage
        {
            get { return this[ApplicationServiceStatesEnum.ReceivingMessage]; }
            set { this[ApplicationServiceStatesEnum.ReceivingMessage] = value; NotifyPropertyChange(() => ReceivingMessage, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "CreatingUser" State
        /// </summary>
        public bool CreatingUser
        {
            get { return this[ApplicationServiceStatesEnum.CreatingUser]; }
            set { this[ApplicationServiceStatesEnum.CreatingUser] = value; NotifyPropertyChange(() => CreatingUser, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "DeleteUser" State
        /// </summary>
        public bool DeletingUser
        {
            get { return this[ApplicationServiceStatesEnum.DeletingUser]; }
            set { this[ApplicationServiceStatesEnum.DeletingUser] = value; NotifyPropertyChange(() => DeletingUser, () => IsBusy);  }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "UpdatingUser" State
        /// </summary>
        public bool UpdatingUser
        {
            get { return this[ApplicationServiceStatesEnum.UpdatingUser]; }
            set { this[ApplicationServiceStatesEnum.UpdatingUser] = value; NotifyPropertyChange(() => UpdatingUser, () => IsBusy);  }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "CreatingRoom" State
        /// </summary>
        public bool CreatingRoom
        {
            get { return this[ApplicationServiceStatesEnum.CreatingRoom]; }
            set { this[ApplicationServiceStatesEnum.CreatingRoom] = value; NotifyPropertyChange(() => CreatingRoom, () => IsBusy);  }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "JoiningRoom" State
        /// </summary>
        public bool JoiningRoom
        {
            get { return this[ApplicationServiceStatesEnum.JoiningRoom]; }
            set { this[ApplicationServiceStatesEnum.JoiningRoom] = value; NotifyPropertyChange(() => JoiningRoom, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "LeavingRoom" State
        /// </summary>
        public bool LeavingRoom
        {
            get { return this[ApplicationServiceStatesEnum.LeavingRoom]; }
            set { this[ApplicationServiceStatesEnum.LeavingRoom] = value; NotifyPropertyChange(() => LeavingRoom, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "FindingRoom" State
        /// </summary>
        public bool FindingRoom
        {
            get { return this[ApplicationServiceStatesEnum.FindingRoom]; }
            set { this[ApplicationServiceStatesEnum.FindingRoom] = value; NotifyPropertyChange(() => FindingRoom, () => IsBusy); }
        }
        /// <summary>
        /// Obtains or defines if the Application is in a "UpdatingRoom" State
        /// </summary>
        public bool UpdatingRoom
        {
            get { return this[ApplicationServiceStatesEnum.UpdatingRoom]; }
            set { this[ApplicationServiceStatesEnum.UpdatingRoom] = value; NotifyPropertyChange(() => UpdatingRoom, () => IsBusy); }
        }
    }
}